/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.scene.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.koron.common.bean.DepartmentTreeBean;
import com.koron.common.bean.StaffBean;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.web.Util;
import com.koron.scene.domain.*;
import com.koron.scene.mapper.DangerousOperationMapper;
import com.koron.scene.mapper.DangerousOperationRelationMapper;
import com.koron.scene.mapper.MomentsMapper;
import com.koron.scene.service.api.DangerousOperationService;
import com.koron.scene.service.api.MomentsService;
import com.koron.scene.utils.BusinessCode;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MomentsServiceImpl implements MomentsService {

    private final static Logger logger = LoggerFactory.getLogger(MomentsServiceImpl.class);
    @Autowired
    private DangerousOperationService dangerousOperationService;

    @Autowired
    private Util util;

    @Override
    public MessageBean<DataBean<Moments>> list(SessionFactory factory, StaffBean user, String corpCode, Integer page, Integer pageSize) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), DataBean.class);
        List<Moments> momentsList = new ArrayList<>();
        MomentsMapper mapper = factory.getMapper(MomentsMapper.class);
        Integer start = null;
        if (page == null || page <= 0) {
            page = 1;
            if (pageSize == null || pageSize <= 0) {
                pageSize = 10;
            }
        }
        start = (page <= 1) ? 0 : (page - 1) * pageSize;
        String codes = util.getCodes(corpCode);
        List<DangerousOperation> dangerousOperationList = factory.getMapper(DangerousOperationMapper.class).getDangerousOperationList(codes, start, pageSize);
        Integer totalCount = factory.getMapper(DangerousOperationMapper.class).getDangerousOperationCount(codes);
        Integer totalPage = (totalCount > pageSize) ? (totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1) : 1;
        // 根据作业票生成对应的朋友圈
        if (null != dangerousOperationList && dangerousOperationList.size() > 0) {
            for (DangerousOperation operation : dangerousOperationList) {
                //设置朋友圈内容
                String content = setMomentsContent(operation);
                List<String> images = new ArrayList<>();
                List<SafetyMeasure> safetyMeasureList = factory.getMapper(DangerousOperationRelationMapper.class).getSafetyByDangerousId(operation.getId());
                if (null != safetyMeasureList && safetyMeasureList.size() > 0) {
                    // 获取安全措施现场图片
                    for (SafetyMeasure safetyMeasure : safetyMeasureList) {
                        if (StringUtils.isNotEmpty(safetyMeasure.getAttachment())) {
                            List<String> list = JSONObject.parseArray(safetyMeasure.getAttachment(), String.class);
                            images.addAll(list);
                        }
                    }
                }
                Moments moments = new Moments();
                moments.setMomentId(operation.getId());
                moments.setContent(content);
                moments.setImages(new Gson().toJson(images));
                moments.setAddUser(operation.getAddUser());
                MessageBean<?> corpMsg = util.corp(operation.getAddUser());
                if (corpMsg.getCode() == 0 && null != corpMsg.getData()) {
                    DepartmentTreeBean corp = (DepartmentTreeBean) corpMsg.getData();
                    moments.setAddUserName(operation.getAddUserName() + "_" + corp.getName());
                } else {
                    moments.setAddUserName(operation.getAddUserName());
                }
                moments.setAddTime(operation.getAddTime());
                momentsList.add(moments);
            }
        }
        // 获取评论及点赞数据
        if (null != momentsList && momentsList.size() > 0) {
            momentsList.forEach(moments -> {
                //  获取评论数据
                List<MomentsComment> commentList = mapper.getMomentsComment(moments.getMomentId());
                if (null != commentList) {
                    commentList.forEach(c -> {
                        if (StringUtils.isNotEmpty(c.getCommentId())) {
                            // 获取回复的人信息
                            String replyName = commentList.stream().filter(comment1 -> c.getCommentId().equals(comment1.getId())).map(comment1 -> comment1.getAddUserName()).collect(Collectors.joining());
                            c.setReply(replyName);
                        }
                    });
                    moments.setCommentsNum(commentList.size());
                    moments.setCommentList(commentList);
                }
                // 获取点赞数据
                List<MomentsLike> likeList = mapper.getMomentsLike(moments.getMomentId());
                if (null != likeList) {
                    // 获取点赞人姓名
                    String likeUserName = likeList.stream().map(momentsLike -> momentsLike.getAddUserName()).collect(Collectors.joining(","));
                    moments.setLikeNum(likeList.size());
                    moments.setLikeUserName(likeUserName);
                    List<MomentsLike> collect = likeList.stream().filter(momentsLike -> momentsLike.getAddUser().equals(user.getCode())).collect(Collectors.toList());
                    if (collect.size() > 0) {
                        moments.setState(true);
                    } else {
                        moments.setState(false);
                    }
                }
            });
        }
        DataBean dataBean = new DataBean<>();
        dataBean.setList(momentsList);
        dataBean.setTotalPage(totalPage);
        dataBean.setTotalNumber(totalCount);
        dataBean.setPageSize(pageSize);
        msg.setData(dataBean);
        return msg;
    }

    /**
     * 设置朋友圈内容
     *
     * @param operation
     * @return
     */
    private String setMomentsContent(DangerousOperation operation) {
        StringBuffer sb = new StringBuffer();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分");
        // 朋友圈内容包括作业类型，作业时间，作业地点，作业单位等相关信息
        sb.append("作业编号：").append(operation.getOperationCode());
        sb.append("。\n作业类型：").append(operation.getOperationTicketTypeName());
        if (null != operation.getOperationStartTime()) {
            sb.append("。\n开始时间：").append(dateFormat.format(operation.getOperationStartTime()));
        }
        // 根据不同的作业票分类和作业票类型生成对应的内容
        Integer check = dangerousOperationService.check(operation.getOperationCategory(), operation.getOperationTicketType());
        switch (check) {
            case 1:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 2:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 3:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 4:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 5:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 6:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 7:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 8:
                setContent(sb, "。\n作业部位：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 9:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 10:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 11:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 12:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 13:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 14:
                setContent(sb, "。\n项目名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 15:
                setContent(sb, "。\n项目名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 16:
                setContent(sb, "。\n项目名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 17:
                setContent(sb, "。\n项目名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 18:
                setContent(sb, "。\n项目名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 19:
                setContent(sb, "。\n项目名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 20:
                setContent(sb, "。\n项目名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
//            case 21:
//                setContent(sb, "。\n项目名称：", operation.getOperationName());
//                setContent(sb, "。\n所在单位：", operation.getOperatingUnitName());
//                break;
            case 22:
                setContent(sb, "。\n项目名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 23:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 24:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 25:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 26:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 27:
                setContent(sb, "。\n作业地点：", operation.getOperatingLocation());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 28:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 29:
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            case 30:
                setContent(sb, "。\n工程名称：", operation.getOperationName());
                setContent(sb, "。\n作业单位：", operation.getConstructionUnitName());
                break;
            default:
                break;
        }
        if (null != operation.getStatus()) {
            sb.append("。\n作业状态：").append(operation.getStatus() == 3 ? "已完工" : "生效中");
        }
        return sb.toString();
    }

    private void setContent(StringBuffer content, String key, String value) {
        if (StringUtils.isNotEmpty(value)) {
            content.append(key).append(value);
        }
    }

    @Override
    public MessageBean<Moments> queryOne(SessionFactory factory, StaffBean user, String id) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Moments.class);
        MomentsMapper mapper = factory.getMapper(MomentsMapper.class);
        try {
            DangerousOperation operation = factory.getMapper(DangerousOperationMapper.class).queryOne(id);
            if (null == operation) {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("动态不存在或已删除");
                return msg;
            }
            StringBuffer sb = new StringBuffer();
            //设置朋友圈内容
            sb.append(operation.getOperationTicketTypeName()).append(operation.getOperationStartTime()).append(operation.getOperatingLocation()).append(operation.getOperatingUnitName());
            List<String> images = new ArrayList<>();
            List<SafetyMeasure> safetyMeasureList = operation.getSafetyMeasureList();
            if (null != safetyMeasureList && safetyMeasureList.size() > 0) {
                // 获取安全措施现场图片
                for (SafetyMeasure safetyMeasure : safetyMeasureList) {
                    if (StringUtils.isNotEmpty(safetyMeasure.getAttachment())) {
                        List<String> list = JSONObject.parseArray(safetyMeasure.getAttachment(), String.class);
                        images.addAll(list);
                    }
                }
            }
            Moments moments = new Moments();
            moments.setMomentId(operation.getId());
            moments.setContent(sb.toString());
            moments.setImages(new Gson().toJson(images));
            moments.setAddUser(operation.getAddUser());
            moments.setAddUserName(operation.getAddUserName());
            moments.setAddTime(operation.getAddTime());
            // 获取评论及点赞数据
            //  获取评论数据
            List<MomentsComment> commentList = mapper.getMomentsComment(moments.getMomentId());
            moments.setCommentsNum(commentList.size());
            moments.setCommentList(commentList);
            // 获取点赞数据
            List<MomentsLike> likeList = mapper.getMomentsLike(moments.getMomentId());
            String likeUserName = likeList.stream().map(like -> like.getAddUserName()).collect(Collectors.joining(","));
            moments.setLikeNum(likeList.size());
            moments.setLikeUserName(likeUserName);
            List<MomentsLike> collect = likeList.stream().filter(momentsLike -> momentsLike.getAddUser().equals(user.getCode())).collect(Collectors.toList());
            if (collect.size() > 0) {
                moments.setState(true);
            } else {
                moments.setState(false);
            }
            msg.setData(moments);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<?> saveComment(SessionFactory factory, StaffBean user, String momentId, String commentId, String content) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        try {
            if (StringUtils.isEmpty(momentId)) {
                return MessageBean.create(BusinessCode.FAILURE.getCode(), "朋友圈动态id不能为空", void.class);
            }
            if (StringUtils.isEmpty(content)) {
                return MessageBean.create(BusinessCode.FAILURE.getCode(), "评论内容不能为空", void.class);
            }
            DangerousOperation operation = factory.getMapper(DangerousOperationMapper.class).queryOne(momentId);
            if (null == operation) {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("动态不存在或已删除");
                return msg;
            }
            // 保存评价
            MomentsComment comment = new MomentsComment();
            comment.setMomentId(momentId);
            comment.setCommentId(commentId);
            comment.setContent(content);
            comment.setAddUser(user.getCode());
            comment.setAddUserName(user.getName());
            comment.setAddTime(new Date());
            comment.setId(DefaultIdGenerator.getInstance().generateLongId());
            Integer integer = factory.getMapper(MomentsMapper.class).insertComment(comment);
            if (integer <= 0) {
                factory.close(false);
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription(BusinessCode.FAILURE.getDescription());
                return msg;
            }
            // 获取最新的评论数据
            List<MomentsComment> commentList = factory.getMapper(MomentsMapper.class).getMomentsComment(momentId);
            commentList.forEach(c -> {
                if (StringUtils.isNotEmpty(c.getCommentId())) {
                    // 获取回复的人信息
                    String replyName = commentList.stream().filter(comment1 -> c.getCommentId().equals(comment1.getId())).map(comment1 -> comment1.getAddUserName()).collect(Collectors.joining());
                    c.setReply(replyName);
                }
            });
            msg.setData(commentList);
            factory.close();
            return msg;
        } catch (Exception e) {
            if (null != factory) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<?> commentDetails(SessionFactory factory, String id) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        try {
            MomentsComment comment = factory.getMapper(MomentsMapper.class).queryComment(id);
            if (null == comment) {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("评论不存在");
                return msg;
            }
            msg.setData(comment);
            return msg;
        } catch (Exception e) {
            if (null != factory) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<?> saveLike(SessionFactory factory, StaffBean user, String momentId) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        try {
            if (StringUtils.isEmpty(momentId)) {
                return MessageBean.create(BusinessCode.FAILURE.getCode(), "朋友圈动态id不能为空", void.class);
            }
            DangerousOperation operation = factory.getMapper(DangerousOperationMapper.class).queryOne(momentId);
            if (null == operation) {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("动态不存在或已删除");
                return msg;
            }
            // 先确定当前用户是否已经点赞（未点赞，保存点赞，已点赞，取消点赞）
            MomentsLike momentsLike = factory.getMapper(MomentsMapper.class).getMomentsLikeOfUser(user.getCode(), momentId);
            if (null == momentsLike) {
                // 如果没有点赞，则保存当前用户点赞数据
                momentsLike = new MomentsLike();
                momentsLike.setMomentId(momentId);
                momentsLike.setAddTime(new Date());
                momentsLike.setAddUser(user.getCode());
                momentsLike.setAddUserName(user.getName());
                momentsLike.setId(DefaultIdGenerator.getInstance().generateLongId());
                factory.getMapper(MomentsMapper.class).insertLike(momentsLike);
            } else {
                // 如果已经点赞，则取消点赞
                factory.getMapper(MomentsMapper.class).deleteLike(momentsLike.getId());
            }
            // 获取当前最新的点赞数据
            List<MomentsLike> momentsLikes = factory.getMapper(MomentsMapper.class).getMomentsLike(momentId);
            String userNameLike = momentsLikes.stream().map(like -> like.getAddUserName()).collect(Collectors.joining(","));
            msg.setData(userNameLike);
            factory.close();
            return msg;
        } catch (Exception e) {
            if (null != factory) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            return msg;
        }
    }
}
